' miniXML.bmx

Strict

Type TAttribute
	Field name$
	Field value$
	Field data:Object
	Function Create:TAttribute(n$,v$)
		Local a:TAttribute=New TAttribute
		a.name=n
		a.value=v
		Return a
	End Function
End Type

Type TElement 
	Field name$="Root"
	Field attributes:TList=New TList
	Field content:TList=New TList
	Field value:Object
	Field parent:TElement
	Field tab$
	
	Method Evaluate()
		Local c$,v$
		Local e:TElement
		Local f#[],i,ff#,p
		For e=EachIn content
			e.Evaluate
		Next		
		For c=EachIn content
			v=v+c+"~n"
		Next
'		If Float(v) 
			f=New Float[1024]
			While v And i<1024
				f[i]=Float(v)
				p=v.find(" ")
				If p=-1 p=Len v
				v=v[p..].Trim()
				i=i+1
			Wend
			value=f[..i]
'		EndIf
	End Method

	Method ReadAttributes(args$)
		Local p,n$,v$
		While args
			p=args.find("=")
			If p=-1 Exit
			n=args[..p]
			args=args[p+1..].Trim()
			If args[..1]="~q"
				args=args[1..]
				p=args.find("~q")
			Else
				p=args.find(" ",1)
			EndIf
			If p=-1 p=Len args
			v$=args[..p]
			args=args[p+1..]
			attributes.AddLast TAttribute.Create(n,v)		
		Wend	
	End Method
	
	Function ObjectValue$(o:Object)
		Local ff#[],f#
		Local i,r$,n

		ff=Float[](o)
		If ff
			For f=EachIn ff
				n:+1
				If n=12 r=r+"..";Exit
				If r r=r+","
				r$=r$+f
			Next
			r$="["+r$+"]"
		EndIf
		Return r
	End Function
	
	Method ToDump$()
		Local e:TElement
		Local o:Object
		Local t$
		t$=ToString()
		For o=EachIn content
			t$=t$+"~n"+tab$+o.ToString$()
		Next		
		If value
			t$=t$+"~n"+tab$+ObjectValue(value)
		EndIf
		Return t
	End Method
	
	Method ToString$()
		Local t$
		Local a:TAttribute
		t$="<"+name
		For a=EachIn attributes
			t=t+" "+a.name+"="+a.value
		Next
		t=t+">"
		Return t
	End Method
Rem
	Method ToString$()
		Local t$
		Local a:TAttribute
		Local e:TElement
		Local o:Object
		t$="<"+name
		For a=EachIn attributes
			t=t+" "+a.name+"="+a.value
		Next
		t=t+">"
		For o=EachIn content
			t$=t$+"~n"+tab$+o.ToString$()
		Next		
		If value
			t$=t$+"~n"+tab$+ObjectValue(value)
		EndIf
		Return t
	End Method
EndRem
End Type

Function LoadXML:TElement(url:Object)
	Local root:TElement
	Local source$
	source=LoadText(url)
	If source="" Return
	root=ParseXML(source)
	Return root
End Function

Function ParseXML:TElement(data$)
	Local root:TElement
	Local current:TElement
	Local element:TElement
	Local p,q,n$,a$,v$
	Local pop,pos
	
	root=New TElement
	current=root
	data=data.replace("~t"," ")
	data=data.replace("~n"," ")
	While pos<Len data
		n=""
		p=data.find("<",pos)
		If p<>pos
			If p=-1 p=Len data
			n=data[pos..p]
			pos=p
			n=n.Trim()
			If n<>"" 
				Current.content.AddLast n
			EndIf
		Else
			q=data.find(">",p)
			If q=-1 Return	'bail if unmatched tags
			n=data[p+1..q].Trim()
			pos=q+1
			pop=0
			If n[0..1]=("/")
				n=n[1..]
				pop=1
			EndIf
			If n[Len n-1..]="/"
				pop=2
				n=n[..Len n-1]
			EndIf			
			If n$[0..1]="?" 
				Continue
			EndIf
			a=""
			p=n.find(" ")
			If p<>-1
				a$=n[p+1..].Trim()
				n=n[..p]
			EndIf
			If pop=1
				current=current.parent
			Else
				element=New TElement
				element.name=n
				current.content.AddLast element
				element.parent=current
				element.tab=current.tab+"~t"
				If pop<>2
					current=element
				EndIf
				If a element.ReadAttributes a				
			EndIf
		EndIf
	Wend
	Return root
End Function 


